package com.gitee.sop.layui.adminserver.module.background.system.api.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gitee.easyopen.doc.annotation.ApiDoc;
import com.gitee.easyopen.doc.annotation.ApiDocMethod;
import com.gitee.easyopen.util.CopyUtil;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.param.LimitNewAddParam;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.param.LimitNewParam;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.param.LimitNewUpdateParam;
import com.gitee.sop.layui.adminserver.module.background.system.api.service.result.LimitNewVO;
import com.gitee.sop.layui.adminserver.module.background.system.bean.ConfigLimitDto;
import com.gitee.sop.layui.adminserver.module.background.system.entity.ConfigLimit;
import com.gitee.sop.layui.adminserver.module.background.system.mapper.ConfigLimitMapper;
import com.gitee.sop.layui.adminserver.module.background.system.service.RouteConfigService;
import com.gitee.sop.layui.adminserver.module.base.constants.Result;
import com.gitee.sop.layui.adminserver.module.base.error.ServiceInterruptionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 限流
 *
 * @author admin
 */
@RestController
@ApiDoc("服务管理-限流管理")
@Slf4j
public class LimitNewApi {

    @Autowired
    RouteConfigService routeConfigService;

    @Autowired
    ConfigLimitMapper configLimitMapper;

    @GetMapping("/api/config.limit.lists")
    @ApiDocMethod(description = "限流列表(新)", elementClass = LimitNewVO.class)
    Result listLimit(LimitNewParam param) {
        Page<ConfigLimit> page = new Page<>(param.getPageIndex(), param.getPageSize());
        LambdaQueryWrapper<ConfigLimit> wrapper = new QueryWrapper<ConfigLimit>().lambda().orderByAsc(ConfigLimit::getRouteId, ConfigLimit::getAppKey, ConfigLimit::getOrderIndex);
        wrapper.eq(StringUtils.isNotBlank(param.getServiceId()), ConfigLimit::getServiceId, param.getServiceId());
        wrapper.like(StringUtils.isNotBlank(param.getRouteId()), ConfigLimit::getRouteId, param.getRouteId());
        wrapper.like(StringUtils.isNotBlank(param.getAppKey()), ConfigLimit::getAppKey, param.getAppKey());
        wrapper.like(StringUtils.isNotBlank(param.getLimitIp()), ConfigLimit::getLimitIp, param.getLimitIp());
        configLimitMapper.selectPage(page, wrapper);
        return Result.successPage(page.getRecords(), page.getTotal(), page.getCurrent(), page.getSize());
    }

    @PostMapping("/api/config.limit.add")
    @ApiDocMethod(description = "新增限流(新)")
    @Transactional(rollbackFor = Exception.class)
    public Result createLimtit(LimitNewAddParam param) {
        ConfigLimit configLimit = new ConfigLimit();
        CopyUtil.copyPropertiesIgnoreNull(param, configLimit);
        configLimitMapper.insert(configLimit);
        ConfigLimitDto configLimitDto = buildConfigLimitDto(configLimit);
        try {
            routeConfigService.sendLimitConfigMsg(configLimitDto);
        } catch (Exception e) {
            log.error("推送限流消息错误, param:{}", param, e);
            throw ServiceInterruptionException.fail(500, "新增失败，请查看日志");
        }
        return Result.success();
    }

    @PostMapping("/api/config.limit.update")
    @ApiDocMethod(description = "修改限流(新)")
    @Transactional(rollbackFor = Exception.class)
    public Result updateLimtit(LimitNewUpdateParam param) {
        ConfigLimit configLimit = configLimitMapper.selectById(param.getId());
        if (configLimit == null) {
            configLimit = new ConfigLimit();
            CopyUtil.copyPropertiesIgnoreNull(param, configLimit);
            configLimitMapper.insert(configLimit);
        } else {
            CopyUtil.copyPropertiesIgnoreNull(param, configLimit);
            configLimitMapper.updateById(configLimit);
        }
        ConfigLimitDto configLimitDto = buildConfigLimitDto(configLimit);
        try {
            routeConfigService.sendLimitConfigMsg(configLimitDto);
        } catch (Exception e) {
            log.error("推送限流消息错误, param:{}", param, e);
            throw ServiceInterruptionException.fail(500, "修改失败，请查看日志");
        }
        return Result.success();
    }

    @GetMapping("/api/config.limit.get")
    @ApiDocMethod(description = "获取指定限流信息")
    @Transactional(rollbackFor = Exception.class)
    public Result getLimtit(Long id) {
        ConfigLimit configLimit = configLimitMapper.selectById(id);
        return Result.success(configLimit);
    }

    private ConfigLimitDto buildConfigLimitDto(ConfigLimit configLimit) {
        ConfigLimitDto configLimitDto = new ConfigLimitDto();
        CopyUtil.copyPropertiesIgnoreNull(configLimit, configLimitDto);
        return configLimitDto;
    }
}
